/*
 * Copyright (c) 2008-2015 Travis Geiselbrecht
 *
 * Use of this source code is governed by a MIT-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/MIT
 */
#include <lk/asm.h>
#include <lk/compiler.h>


/*****************************************************************************/
/* Version: GCC for ARM Embedded Processors                                  */
/*****************************************************************************/

    .syntax unified
    .arch armv7-m

/* Reset Handler */

    .thumb_func
    .align 2
    .globl   _start
    .type    _start, %function
_start:
    cpsid   i               /* Mask interrupts */
 
    ldr r0, =0x400ac044   //Address of register IOMUXC_GPR_GPR17
    ldr r1, =0x00005555   //FlexRAM configuration DTC = 128KB, ITC = 64KB, OC = 64KB
    STR r1,[r0]   

    ldr r0, =0x400ac040   //Address of register IOMUXC_GPR_GPR16
    ldr r1, [r0]   
    orr r1, r1, #4   //The 4 corresponds to setting the FLEXRAM_BANK_CFG_SEL bit in register IOMUXC_GPR_GPR16
    str r1, [r0]   

    // FLEXRAM_ITCM_ZERO_SIZE = 0, FLEXRAM_DTCM_ZERO_SIZE = 0
    ldr r0, =0x400ac040   //Address of register IOMUXC_GPR_GPR16
    ldr r1, [r0]   
    and r1, r1, #0xfffffffc    //Disabling SRAM_ITC and SRAM_DTCin register IOMUXC_GPR_GPR16
    str r1, [r0]   

    ldr r0, =0x400ac038   //Address of register IOMUXC_GPR_GPR14
    ldr r1, =0x000000   //New size configuration for the IOMUXC_GPR_GPR14 register
    str r1, [r0]

    .equ    VTOR, 0xE000ED08
    ldr     r0, =VTOR
    ldr     r1, =__VECTOR_TABLE
    str     r1, [r0]
    ldr     r2, [r1]
    msr     msp, r2
#ifndef __NO_SYSTEM_INIT
    ldr   r0,=SystemInit
    blx   r0
#endif
/*     Loop to copy data from read only memory to RAM. The ranges
 *      of copy from/to are specified by following symbols evaluated in
 *      linker script.
 *      __etext: End of code section, i.e., begin of data sections to copy from.
 *      __data_start__/__data_end__: RAM address range that data should be
 *      __noncachedata_start__/__noncachedata_end__ : none cachable region
 *      __ram_function_start__/__ram_function_end__ : ramfunction region
 *      copied to. Both must be aligned to 4 bytes boundary.  */

    ldr    r1, =__rodata_start
    ldr    r2, =__data_start
    ldr    r3, =__data_end
.LC0:
    cmp     r2, r3
    ittt    lt
    ldrlt   r0, [r1], #4
    strlt   r0, [r2], #4
    blt    .LC0

#ifdef __STARTUP_CLEAR_BSS
/*     This part of work usually is done in C library startup code. Otherwise,
 *     define this macro to enable it in this startup.
 *
 *     Loop to zero out BSS section, which uses following symbols
 *     in linker script:
 *      __bss_start__: start of BSS section. Must align to 4
 *      __bss_end__: end of BSS section. Must align to 4
 */
    ldr r1, =__bss_start__
    ldr r2, =__bss_end__

    movs    r0, 0
.LC5:
    cmp     r1, r2
    itt    lt
    strlt   r0, [r1], #4
    blt    .LC5
#endif /* __STARTUP_CLEAR_BSS */

//    cpsie   i               /* Unmask interrupts */
#ifndef __START
#define __START arm_m_start
#endif
#ifndef __ATOLLIC__
    ldr   r0,=__START
    blx   r0
#else
    ldr   r0,=__libc_init_array
    blx   r0
    ldr   r0,=main
    bx    r0
#endif

    .pool
    .size _start, . - _start

    .end